package com.boarsoft.boar.code.agent.service;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.FutureTask;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;

import com.boarsoft.boar.code.agent.bean.FileCodeBean;
import com.boarsoft.boar.code.bean.service.BeanService;
import com.boarsoft.common.Util;

@Component("codeService")
@PropertySource("classpath:conf/config.properties")
public class CodeServiceImpl implements CodeService {
	private static final Logger log = LoggerFactory.getLogger(CodeServiceImpl.class);

	@Autowired
	private BeanService beanService;

	// 文件扫描路径
	@Value("${scan.path}")
	private String scanPath;

	// 文件下载路径
	@Value("${write.path}")
	private String writePath;

	// 服务配置
	@Value("${scan.serviceType}")
	private String serviceType;

	// bean配置
	@Value("${scan.beanType}")
	private String beanType;

	@Override
	public void scan(String dir) throws IOException {
		if (Util.strIsEmpty(dir)) {
			dir = scanPath;
		}
		log.info("Scan source code dir {}", dir);
		List<Path> fpLt = this.getFilePath(dir);
		ExecutorService executorService = Executors.newFixedThreadPool(10);
		for (Path path : fpLt) {
			String cont = readFile(path);
			String fileType = getfileType(path);
			FileCodeBean fcb = new FileCodeBean();
			fcb.setFileName(path.toString());
			fcb.setFileType(fileType);
			fcb.setCont(cont);
			//调用源码解析和存储服务
//			beanService.save(fcb.getFileType(), fcb.getCont());

			//异步调源码解析和存储服务
			FutureTask<String> beanSaveTask = new FutureTask<>(new Callable<String>() {
				@Override
				public String call() throws Exception {
					return beanService.save(fcb.getFileType(), fcb.getCont());
				}
			});
			executorService.submit(beanSaveTask);

		}

		//调用用户服务获取用户基本信息

	}

	private String readFile(Path path) throws IOException {
		byte[] bytes = Files.readAllBytes(path);
		return new String(bytes, StandardCharsets.UTF_8);
	}

	private List<Path> getFilePath(String dir) throws IOException {
		Stream<Path> pathStream = Files.walk(Paths.get(dir));
		try {
			List<Path> pathList = pathStream.filter(fileName -> //
			(isScaner(fileName.toString()))).collect(Collectors.toList());
			return pathList;
		} finally {
			pathStream.close();
		}
	}

	private boolean isScaner(String filename) {
		return isService(filename) || isBean(filename);
	}

	private boolean isService(String filename) {
		return isType(serviceType, filename);
	}

	private boolean isBean(String filename) {
		return isType(beanType, filename);
	}

	private boolean isType(String typeConfig, String str) {
		Pattern pattern = Pattern.compile(typeConfig, Pattern.CASE_INSENSITIVE);
		return pattern.matcher(str).matches() && str.endsWith(".java");
	}

	@Override
	public String write(String projCode, String className, String content) throws Throwable {
		// TODO 配置
		String path = this.writePath + "\\" + projCode + "\\" + className.replace(".", "\\") + ".java";
		// 文件路径
		Path filePath = Paths.get(path);
		// 文件所在目录
		Path dir = filePath.getParent();
		Files.createDirectories(dir);
		Path p = Files.write(filePath, content.getBytes("utf-8"));
		return p.toString();
	}

	public String getfileType(Path path) {
		String fileType = "interface";
		if (isBean(path.toString())) {
			fileType = "bean";
		}
		return fileType;
	}
}